1 00:00:00,080 --> 00:00:00,710 Hey there. 2 00:00:00,710 --> 00:00:01,700 Welcome back. 3 00:00:01,700 --> 00:00:06,800 This lecture is going to be a little fun because we're going to learn about a new service called the 4 00:00:06,800 --> 00:00:11,180 Tween Service, which allows you to animate values in your game. 5 00:00:11,180 --> 00:00:17,450 The result of this ability to tween or animate the values in your game allows you to do different things, 6 00:00:17,450 --> 00:00:21,890 like maybe animate the position of objects from one place to another. 7 00:00:21,890 --> 00:00:29,140 You could animate the colors of objects, you could animate the lighting in your game and there's so 8 00:00:29,140 --> 00:00:31,960 much more things you could do with the tween service. 9 00:00:31,960 --> 00:00:34,330 So what exactly is the tween service? 10 00:00:34,330 --> 00:00:37,330 Well, the Roblox documentation should be able to help us out. 11 00:00:37,360 --> 00:00:44,020 Tweens, which are the objects created by the tween service, are used to interpolate the properties 12 00:00:44,020 --> 00:00:45,310 of instances. 13 00:00:45,310 --> 00:00:49,540 These can be used to create animations for various Roblox objects. 14 00:00:49,540 --> 00:00:53,370 Almost any numeric property can be tweened using tween service. 15 00:00:53,400 --> 00:00:57,690 Note that only specific types of properties can be used with tween service. 16 00:00:57,690 --> 00:01:04,440 The types of properties that can be tweened are going to be numbers, booleans, see frames, rect objects, 17 00:01:04,440 --> 00:01:12,270 or the rect data type color threes Udims which is for UI vector twos, vector threes and enum items. 18 00:01:12,960 --> 00:01:19,720 Tween services constructor function tween service create takes information about the animation and generates 19 00:01:19,720 --> 00:01:22,840 the tween object, which can be used to play the animation. 20 00:01:22,840 --> 00:01:27,130 Note that tweens can animate multiple properties at the same time. 21 00:01:27,130 --> 00:01:33,430 Details on how the interpolation of the tween is to be carried out are given in the tween info parameter 22 00:01:33,430 --> 00:01:35,350 of the create constructor. 23 00:01:35,350 --> 00:01:40,750 The tween info data type includes a range of properties that can be used to achieve various styles of 24 00:01:40,750 --> 00:01:43,330 animations, including reversing and looping. 25 00:01:43,360 --> 00:01:43,960 Tweens. 26 00:01:43,960 --> 00:01:49,300 Multiple tweens can be played on the same object at the same time, but they must not be animating the 27 00:01:49,300 --> 00:01:50,170 same property. 28 00:01:50,170 --> 00:01:56,020 If two tweens attempt to modify the same property, the initial tween will be cancelled and overwritten 29 00:01:56,020 --> 00:01:57,640 by the most recent tween. 30 00:01:57,640 --> 00:02:02,860 Although other methods exist for tweening objects such as tween size and position. 31 00:02:02,860 --> 00:02:07,880 For GUI objects, the tween service allows multiple properties to be modified, and for the animation 32 00:02:07,880 --> 00:02:10,880 to be paused and canceled at any point. 33 00:02:10,880 --> 00:02:16,370 If we take a look at the constructor function, which is called create, it has three parameters. 34 00:02:16,370 --> 00:02:19,940 The first parameter is going to be the instance that needs to be tweened. 35 00:02:19,940 --> 00:02:25,070 The tween info is going to describe how this animation is going to play out. 36 00:02:25,070 --> 00:02:30,820 And then this last parameter is a table that's going to contain a dictionary of properties. 37 00:02:30,820 --> 00:02:32,860 So it's going to be the name of the property. 38 00:02:32,860 --> 00:02:36,850 And then the target value that we're going to tween towards. 39 00:02:36,850 --> 00:02:39,820 Let's go ahead and take a look at a tween info. 40 00:02:40,840 --> 00:02:46,660 So it says a tween info data type stores parameters for the constructor to specify the behavior of the 41 00:02:46,660 --> 00:02:47,200 tween. 42 00:02:47,200 --> 00:02:52,210 And it has a constructor tween info dot new and it accepts several different parameters. 43 00:02:52,210 --> 00:02:56,160 The first is going to be the time or the duration of the tween. 44 00:02:56,160 --> 00:03:02,370 The next is going to be the easing style of the tween, the easing direction, whether or not the tween 45 00:03:02,370 --> 00:03:09,210 repeats, whether or not the tween reverses, and the delay time before playing the tween. 46 00:03:09,210 --> 00:03:15,120 Thankfully, Roblox gives us some examples of what the different easing styles and easing directions 47 00:03:15,120 --> 00:03:15,480 do. 48 00:03:15,480 --> 00:03:21,470 So they give us several graphs with the easing direction first set to N, and it tells us each of the 49 00:03:21,470 --> 00:03:22,340 different styles. 50 00:03:22,340 --> 00:03:26,720 So these are all the styles that are available for the easing style. 51 00:03:26,720 --> 00:03:30,980 For example linear sine quad a whole bunch of different mathematical functions. 52 00:03:30,980 --> 00:03:34,460 But if we take a look at the graphs here x represents the number. 53 00:03:34,460 --> 00:03:37,430 So this bottom left represents the starting point. 54 00:03:37,430 --> 00:03:39,410 And then this represents the goal point. 55 00:03:39,410 --> 00:03:45,760 So over time which is t this is how our value is going to change when it's set to the linear easing 56 00:03:45,760 --> 00:03:46,390 style. 57 00:03:46,390 --> 00:03:48,130 This is what it looks like on sine. 58 00:03:48,130 --> 00:03:49,270 This is quad. 59 00:03:49,300 --> 00:03:56,890 This one's cubic quarte quinte exponential circular back bounce and elastic. 60 00:03:56,890 --> 00:04:00,010 And then these graphs also change depending on the easing direction. 61 00:04:00,010 --> 00:04:04,330 So if we look at an easing direction of out you can see that linear stays the same. 62 00:04:04,330 --> 00:04:10,250 But this time what you should notice is that all of these graphs basically got flipped. 63 00:04:10,940 --> 00:04:13,160 So now sine looks like this. 64 00:04:13,160 --> 00:04:15,590 This is how the value is going to change over time. 65 00:04:15,590 --> 00:04:16,910 Same thing with exponential. 66 00:04:16,910 --> 00:04:20,090 You can see how elastic has changed as well as bounced. 67 00:04:20,090 --> 00:04:22,430 Bounce basically flipped itself. 68 00:04:22,430 --> 00:04:27,890 And then with the easy direction set to in and out, this is what the values are going to look like. 69 00:04:27,890 --> 00:04:32,530 You can see that bounce starts bouncing at the beginning, then it reverses and bounces back at the 70 00:04:32,530 --> 00:04:33,190 end. 71 00:04:33,190 --> 00:04:36,580 So basically does the tween for both the beginning and the ending. 72 00:04:36,580 --> 00:04:42,040 When you're set to in and out, when you're set to out, it does the tween basically at the end. 73 00:04:42,040 --> 00:04:47,350 And then when the easing direction is set to in, it does the fancy tween thing at the beginning of 74 00:04:47,350 --> 00:04:50,260 the tween and then it gradually reaches the end. 75 00:04:50,260 --> 00:04:55,380 So those are the different easing directions, each with their own easing styles and how they influence 76 00:04:55,380 --> 00:04:55,800 them. 77 00:04:56,010 --> 00:05:01,050 So let's go ahead and take a look at how we can use the tween service in our scripts. 78 00:05:01,080 --> 00:05:06,780 The first example I want to go ahead and do is tweening the color of a part. 79 00:05:06,780 --> 00:05:09,180 So here's my part right here in the workspace. 80 00:05:09,360 --> 00:05:15,090 Let me add a script inside of it, and let's make a reference to my part, which is simply going to 81 00:05:15,090 --> 00:05:17,250 be script dot parent. 82 00:05:17,540 --> 00:05:20,210 And we want to be able to tween the color of the part. 83 00:05:20,210 --> 00:05:22,790 So let's go ahead and pull in the tween service. 84 00:05:23,150 --> 00:05:26,480 It's going to be game get service tween service. 85 00:05:27,050 --> 00:05:31,160 And we need to create a brand new tween for our part. 86 00:05:31,160 --> 00:05:33,140 So we need to call the create function. 87 00:05:33,140 --> 00:05:39,020 And we need to pass it the instance between info and the goal properties we want to tween to. 88 00:05:39,590 --> 00:05:43,240 So the instance is going to obviously be our part. 89 00:05:43,240 --> 00:05:46,600 And then we need to pass some information about how we want to play this tween. 90 00:05:46,600 --> 00:05:48,790 So let's create a new tween info. 91 00:05:48,790 --> 00:05:52,030 And it's going to be the global of tween info. 92 00:05:52,030 --> 00:05:53,470 So this is a data type. 93 00:05:53,470 --> 00:05:58,000 And we need to use a constructor to create a new tween info. 94 00:05:58,750 --> 00:06:03,340 And then here we can pass a whole bunch of different optional parameters for how we want to customize 95 00:06:03,340 --> 00:06:03,910 the tween. 96 00:06:04,360 --> 00:06:09,540 So just for this example, let's pass a value of one for the time and then the rest. 97 00:06:09,540 --> 00:06:11,760 We're just going to leave at their defaults. 98 00:06:11,760 --> 00:06:13,410 This is going to be our tween info. 99 00:06:13,410 --> 00:06:16,620 And we need to pass this to the tween service. 100 00:06:16,770 --> 00:06:20,370 And then we need to give it the property that we want to tween. 101 00:06:20,370 --> 00:06:23,880 In this case we want to tween the color property of our part. 102 00:06:23,880 --> 00:06:29,700 So we need to make sure that the key is the exact same name as the property for our part. 103 00:06:29,720 --> 00:06:34,400 and we need to set this equal to a new color three or the color three we want to tween to. 104 00:06:34,430 --> 00:06:36,770 So let's make it a little bit random. 105 00:06:36,800 --> 00:06:39,140 Let me create a random number generator here. 106 00:06:39,140 --> 00:06:42,560 So we're going to do RNG equal to random dot new. 107 00:06:42,920 --> 00:06:45,320 And then we're going to create a new color three. 108 00:06:45,320 --> 00:06:47,420 So color three dot new. 109 00:06:47,420 --> 00:06:53,880 And then for each of the red green and blue number components we're just going to do RNG next number. 110 00:06:53,880 --> 00:06:58,560 And we're just going to randomly generate a number for each of the RGB values. 111 00:06:59,610 --> 00:07:04,590 And then once we create the tween we're not done yet because this function is going to return to us 112 00:07:04,590 --> 00:07:06,450 a tween instance. 113 00:07:06,450 --> 00:07:12,240 So we can call a variable tween and set that equal to the return from the create function. 114 00:07:12,450 --> 00:07:16,890 And if we type out the tween here, as you can see it is of the type tween. 115 00:07:16,890 --> 00:07:22,410 It is a tween instance, and this tween instance has several different properties and events and functions 116 00:07:22,410 --> 00:07:23,430 that we can use. 117 00:07:23,430 --> 00:07:30,240 So for example, to start the tween we can call the play function starts playback of a tween. 118 00:07:30,270 --> 00:07:34,470 Note that if playback has already stopped calling, play has no effect unless the tween has finished 119 00:07:34,470 --> 00:07:35,340 or has stopped. 120 00:07:35,340 --> 00:07:37,770 So this is how we can start playing the tween. 121 00:07:38,220 --> 00:07:40,710 And then the tween also has some events in it. 122 00:07:40,710 --> 00:07:45,700 The most notable is going to be the completed event and it says fires when the tween finishes playing 123 00:07:45,700 --> 00:07:48,490 or when stopped when calling the cancel function. 124 00:07:48,490 --> 00:07:53,200 So let's refer to this event and let's connect a lambda function to it. 125 00:07:53,200 --> 00:07:57,370 And all we're going to do is we're just going to print that the tween completed. 126 00:07:58,150 --> 00:08:04,540 So with this code that we now have, let's go ahead and run our game and see if the color of our part 127 00:08:04,540 --> 00:08:05,170 changes. 128 00:08:05,170 --> 00:08:06,390 So if we hit run. 129 00:08:08,550 --> 00:08:09,810 Well, it looks like it did. 130 00:08:09,810 --> 00:08:15,180 It changed to a slightly weird white color, maybe a more beige color. 131 00:08:15,180 --> 00:08:17,580 And we did print the tween completed. 132 00:08:17,610 --> 00:08:20,310 Unfortunately, it didn't really pick a good random color. 133 00:08:20,310 --> 00:08:26,550 So actually let's let's increase the tween info to like maybe five seconds and then let's run it and 134 00:08:26,550 --> 00:08:27,600 see what color we get. 135 00:08:27,960 --> 00:08:28,620 Okay, look at that. 136 00:08:28,620 --> 00:08:31,000 It's slowly changing color. 137 00:08:31,000 --> 00:08:32,440 And then eventually there we go. 138 00:08:32,440 --> 00:08:36,100 The tween completed and it's a nice little purplish blue color. 139 00:08:36,130 --> 00:08:37,450 Let's run the game again. 140 00:08:37,450 --> 00:08:42,100 And let's take a look at how the color property for our part changes over time. 141 00:08:42,100 --> 00:08:48,340 So if we select the part you're going to see that the color property is slowly changing over time until 142 00:08:48,340 --> 00:08:51,010 it reaches the end of the tween and our tween completes. 143 00:08:51,010 --> 00:08:52,510 And this is our new color. 144 00:08:52,510 --> 00:08:53,500 Very cool. 145 00:08:53,560 --> 00:08:59,070 Now if we remember in the documentation, we can tween more than one property at once. 146 00:08:59,070 --> 00:09:04,410 So another example, maybe we want to tween the size of the part at the same time that we're tweening 147 00:09:04,410 --> 00:09:05,730 the color of the part. 148 00:09:05,730 --> 00:09:09,060 So let's create a variable, let's call it new size. 149 00:09:09,090 --> 00:09:11,850 And this is going to be equal to our parts size. 150 00:09:11,850 --> 00:09:14,040 And then let's add a new vector three. 151 00:09:14,040 --> 00:09:20,090 And let's increase the size of this part on I don't know let's increase it on the x axis by like six 152 00:09:20,090 --> 00:09:20,720 stuts. 153 00:09:22,700 --> 00:09:27,530 And then inside of our goal table, let's actually move it to another variable. 154 00:09:27,530 --> 00:09:30,110 We'll call it goal that's equal to a table. 155 00:09:30,110 --> 00:09:33,620 And then let's copy what we have in here. 156 00:09:33,620 --> 00:09:38,990 Paste it in there and we'll pass goal to the tween service create function. 157 00:09:39,200 --> 00:09:43,540 And then the other property we want to go ahead and tween is going to be the size. 158 00:09:44,080 --> 00:09:46,660 And that's going to be equal to our new size. 159 00:09:46,990 --> 00:09:51,940 So let's go ahead and run the tween now and look at that five seconds. 160 00:09:51,940 --> 00:09:54,430 Over time our part is changing color. 161 00:09:54,430 --> 00:09:59,020 But it is also increased in size by six studs on the x axis. 162 00:09:59,020 --> 00:09:59,800 Really cool. 163 00:09:59,830 --> 00:10:01,300 Let's go ahead and do another example. 164 00:10:01,300 --> 00:10:06,160 Let's go ahead and tween the time inside of the lighting service. 165 00:10:06,160 --> 00:10:08,100 So let's tween this value right here. 166 00:10:08,100 --> 00:10:09,060 Clock time. 167 00:10:09,060 --> 00:10:11,970 So let me create a new script and service. 168 00:10:11,970 --> 00:10:12,900 Script service. 169 00:10:14,100 --> 00:10:16,440 Let's go ahead and get the tween service again. 170 00:10:18,240 --> 00:10:20,220 And I want to have a little bit more fun here. 171 00:10:20,220 --> 00:10:24,630 And let's have this tween loop or go in an infinite cycle. 172 00:10:24,630 --> 00:10:31,100 So to do that what we need to do is we need to create a new tween on the lighting service so we could 173 00:10:31,100 --> 00:10:33,650 do game, get service lighting. 174 00:10:33,950 --> 00:10:35,690 We're going to have to pass a tween info. 175 00:10:35,690 --> 00:10:38,150 So let's create a new tween info here. 176 00:10:38,780 --> 00:10:41,180 Call the variable tween info. 177 00:10:41,180 --> 00:10:45,200 And that's going to be equal to tween info dot new the time. 178 00:10:45,200 --> 00:10:49,880 Let's do let's do 10s the easing style. 179 00:10:49,880 --> 00:10:52,520 Let's do the easing style of linear. 180 00:10:52,880 --> 00:10:56,940 We're going to set the easing direction to just the regular one of in. 181 00:10:56,970 --> 00:11:01,470 It doesn't really matter which one we pick because it's not going to change for this particular easing 182 00:11:01,470 --> 00:11:01,770 style. 183 00:11:01,770 --> 00:11:03,360 So we're just going to do in. 184 00:11:03,750 --> 00:11:09,150 And then we want the tween to basically go on for infinity. 185 00:11:09,150 --> 00:11:14,700 And in order to do that, we need to set the repeat count equal to negative one which tells the tween 186 00:11:14,700 --> 00:11:19,040 service, hey, this is going to be a tween that goes on forever and ever and ever. 187 00:11:19,040 --> 00:11:22,940 And then finally, do we want this tween to reverse? 188 00:11:22,940 --> 00:11:25,160 We don't because we want it to go in a loop. 189 00:11:25,160 --> 00:11:27,770 So we're going to set that equal to false. 190 00:11:27,770 --> 00:11:32,630 So now we can pass this to the create function. 191 00:11:32,630 --> 00:11:35,330 And then finally we need to give it the property table. 192 00:11:35,330 --> 00:11:41,480 In this case we want to change the clock time equal to 24. 193 00:11:41,480 --> 00:11:47,890 Because what's going to happen is once the clock time reaches 24, it's going to set itself to zero, 194 00:11:47,890 --> 00:11:49,990 and then we're going to be able to loop again. 195 00:11:49,990 --> 00:11:57,190 And just to make sure we're going to loop properly, let's set the lighting services clock time to zero. 196 00:11:57,190 --> 00:12:01,600 So actually let us make a variable for the lighting service. 197 00:12:01,600 --> 00:12:05,260 We'll call it lighting equal to game and get service lighting. 198 00:12:05,290 --> 00:12:09,060 That way we can pass that variable to the create function. 199 00:12:09,060 --> 00:12:14,460 And before we play our tween, let's go ahead and set the clock time and the lighting service to zero. 200 00:12:14,460 --> 00:12:20,250 And then let's go ahead and store the result of this constructor in our variable. 201 00:12:20,250 --> 00:12:23,640 So that way we can play the tween. 202 00:12:23,880 --> 00:12:25,740 So now let's go ahead and run our game. 203 00:12:26,640 --> 00:12:28,740 And let's see if we can find the sun. 204 00:12:28,740 --> 00:12:29,940 There's the sun. 205 00:12:29,940 --> 00:12:31,640 It's going around. 206 00:12:31,640 --> 00:12:32,840 And then sunset. 207 00:12:32,840 --> 00:12:33,620 Boom. 208 00:12:33,620 --> 00:12:36,800 There's the moon going around. 209 00:12:36,800 --> 00:12:42,500 And then eventually moon's gone and the sun rise is back to a sunset. 210 00:12:42,500 --> 00:12:43,070 Very cool. 211 00:12:43,070 --> 00:12:45,200 Let's go ahead and take a look at the clock time. 212 00:12:45,860 --> 00:12:50,480 So as you can see it gets set to zero and then it increases towards 24 again. 213 00:12:50,480 --> 00:12:53,060 So we're basically going to loop forever. 214 00:12:53,060 --> 00:12:55,960 So once this hits 24 it should go back to zero. 215 00:12:55,990 --> 00:12:57,430 There we go back to zero. 216 00:12:57,430 --> 00:12:58,900 And we are looping again. 217 00:12:58,900 --> 00:13:01,840 So this is our infinite lighting tween. 218 00:13:01,840 --> 00:13:07,960 Now one important thing I want to mention with the tween service is that you should typically avoid 219 00:13:07,960 --> 00:13:10,780 playing tweens on the server. 220 00:13:10,810 --> 00:13:18,590 This is because as the tween interpolates each frame on the server, it has to send that updated information 221 00:13:18,590 --> 00:13:24,200 to all of the clients in the game at each frame, or each step of the twin. 222 00:13:24,260 --> 00:13:31,160 This will result in tweens looking choppy on the client due to the property being replicated every single 223 00:13:31,160 --> 00:13:37,190 frame, and it's also going to result in higher network usage from your server to your clients. 224 00:13:37,190 --> 00:13:42,700 So as the server continues to update and move something or do whatever with a tween. 225 00:13:42,700 --> 00:13:46,930 Every single client in your game is also going to have to do things, but it's going to look like choppy. 226 00:13:46,960 --> 00:13:48,400 It's not going to look very nice. 227 00:13:48,400 --> 00:13:55,030 So instead, what we should do is we should have a way where we can create a tween or basically create 228 00:13:55,030 --> 00:14:00,250 a tween on the server, but instead the server is going to send that information to every single client 229 00:14:00,250 --> 00:14:00,910 in the game. 230 00:14:00,910 --> 00:14:07,320 So that way every single client plays the tween locally on their copy of the game, so it looks nice 231 00:14:07,320 --> 00:14:07,920 and smooth. 232 00:14:07,920 --> 00:14:13,230 So let's just imagine that every single client's playing a very smooth tween, and then once the tween 233 00:14:13,230 --> 00:14:20,010 is over, all the server needs to do is just instantly update the property that we're tweening to the 234 00:14:20,010 --> 00:14:20,880 goal property. 235 00:14:20,880 --> 00:14:27,390 So that way any new clients that join the game in the future will have whatever property we tweened 236 00:14:27,390 --> 00:14:34,070 at the correct goal mark, and then if the server needs to tween it again to a new position, it can 237 00:14:34,070 --> 00:14:35,990 just send all that information to the clients. 238 00:14:35,990 --> 00:14:38,210 The clients can play those tweens. 239 00:14:39,200 --> 00:14:40,700 So it's nice and smooth. 240 00:14:40,700 --> 00:14:46,100 And then once the tweens are over, the server can just instantaneously move the part to the correct 241 00:14:46,100 --> 00:14:46,820 position. 242 00:14:46,820 --> 00:14:52,190 So as an example of this choppiness, let's take a look at the tween that is tweening the color and 243 00:14:52,190 --> 00:14:53,630 the size of our part. 244 00:14:53,630 --> 00:14:55,390 We're doing it from a service script. 245 00:14:55,390 --> 00:14:57,490 So this is a server side tween. 246 00:14:57,490 --> 00:15:02,050 But let's go ahead and play the game and see what the tween looks like on the client. 247 00:15:04,000 --> 00:15:07,960 And you're going to notice that the tween didn't look that bad because we didn't really move it that 248 00:15:07,960 --> 00:15:08,230 much. 249 00:15:08,230 --> 00:15:09,730 And the tween was quite short. 250 00:15:09,730 --> 00:15:14,980 So actually, before we do anything, let's just wait, uh, a few seconds. 251 00:15:14,980 --> 00:15:22,710 So that way the client can load into the game and then let's make the tween longer, like let's do 10s 252 00:15:22,710 --> 00:15:27,780 and then let's increase the size on the x axis by a much larger number like 50. 253 00:15:29,340 --> 00:15:31,440 And then let's play the game. 254 00:15:32,910 --> 00:15:35,430 And right now it doesn't actually look too bad. 255 00:15:35,430 --> 00:15:38,730 You can see it slightly jittering, but it's not that bad. 256 00:15:38,730 --> 00:15:43,960 And that's because I'm hosting this server locally on my computer, so there isn't really any big network 257 00:15:43,960 --> 00:15:45,550 delay or replication issues. 258 00:15:45,550 --> 00:15:51,310 But trust me, if you publish the game and you play twins on the server, all of the clients in your 259 00:15:51,310 --> 00:15:55,570 game are going to notice that the twins are very jittery and they're not that smooth. 260 00:15:56,020 --> 00:16:02,320 So we need to fix this by creating some kind of system that tells all of the clients to play the tween 261 00:16:02,320 --> 00:16:05,620 locally, instead of the server having to play the tweens. 262 00:16:05,620 --> 00:16:10,860 So let's actually work on that together as like a little mini project with the tween service. 263 00:16:10,860 --> 00:16:15,420 Let's create a module script and let's place it in replicated storage. 264 00:16:15,420 --> 00:16:17,610 And let's call this module script. 265 00:16:17,790 --> 00:16:18,330 Uh, I don't know. 266 00:16:18,330 --> 00:16:20,760 We'll call it something like Better Tween. 267 00:16:20,760 --> 00:16:24,780 And we're going to use this module script to create tweens on the server. 268 00:16:24,780 --> 00:16:30,210 And then this module script is going to handle sending that information to all the clients in our game. 269 00:16:30,210 --> 00:16:31,850 The clients playing the tween. 270 00:16:31,850 --> 00:16:37,130 And then when the tween is over, we can have the server apply all of the properties that are in the 271 00:16:37,130 --> 00:16:38,030 goal table. 272 00:16:38,030 --> 00:16:40,010 So let's rename this module here. 273 00:16:40,010 --> 00:16:43,190 We're going to do control shift R to rename it. 274 00:16:43,190 --> 00:16:45,260 We're just going to call it better tween. 275 00:16:45,620 --> 00:16:50,270 And then let's go ahead and create a function inside of this table. 276 00:16:50,270 --> 00:16:51,590 Better tween. 277 00:16:51,590 --> 00:16:55,960 We're going to use a colon to just kind of pronounce this function as a method. 278 00:16:55,960 --> 00:17:00,070 And let's just call it we could call it create similar to the tween service. 279 00:17:00,070 --> 00:17:05,590 Or we could just call it tween as well, since this is technically going to play the tween for us, 280 00:17:05,590 --> 00:17:09,880 and we're going to do the exact same thing as the tween service, we're going to need to be passed an 281 00:17:09,880 --> 00:17:15,760 instance, the tween info for the tween as well as a goal table. 282 00:17:15,790 --> 00:17:20,400 And then basically what we can do from this point is we can use something like a remote event and fire 283 00:17:20,400 --> 00:17:21,990 to all of the clients in the game. 284 00:17:21,990 --> 00:17:23,940 What instance needs to be tween? 285 00:17:23,940 --> 00:17:26,190 Here's the tween info for it as well as the goal. 286 00:17:26,190 --> 00:17:28,200 So the clients can play those tweens. 287 00:17:28,200 --> 00:17:32,250 And then when the tween is over, we'll have the server apply all of the goal properties. 288 00:17:32,250 --> 00:17:35,340 So let's create a remote event. 289 00:17:35,340 --> 00:17:37,620 Let's just make it a child of our module. 290 00:17:37,620 --> 00:17:40,650 And we'll just call this event play tween. 291 00:17:41,550 --> 00:17:43,530 And then up here we can make a reference to it. 292 00:17:43,530 --> 00:17:44,490 We'll just call it event. 293 00:17:44,490 --> 00:17:47,160 And that's going to be equal to script dot play tween. 294 00:17:47,760 --> 00:17:54,270 And then basically what we want to do is we just want to use our event and we want to fire to all clients. 295 00:17:54,270 --> 00:17:58,620 So fire all clients and we need to send them some information. 296 00:17:58,620 --> 00:18:01,470 We need to send them the instance. 297 00:18:01,860 --> 00:18:06,450 We need to send them the tween info, and we need to send them the goal. 298 00:18:06,450 --> 00:18:07,960 So that way they can play the tween. 299 00:18:07,960 --> 00:18:13,780 So then we are going to need a local script on the client to listen to that event. 300 00:18:13,780 --> 00:18:14,980 So let's add one. 301 00:18:14,980 --> 00:18:18,730 Inside of starter player scripts, we'll create a new local script. 302 00:18:19,630 --> 00:18:24,670 We'll make a reference to replicated storage since that is where our module is stored. 303 00:18:24,670 --> 00:18:28,330 So we'll do game get service, replicated storage. 304 00:18:29,050 --> 00:18:31,090 And then we need a reference to our event. 305 00:18:31,090 --> 00:18:32,930 So we'll just call this event as well. 306 00:18:32,930 --> 00:18:38,120 And that's going to be equal to replicated storage dot better tween dot play tween. 307 00:18:38,750 --> 00:18:41,420 Then we need to listen on the client side. 308 00:18:41,420 --> 00:18:44,810 So on client event I'm going to connect a function to this event. 309 00:18:45,740 --> 00:18:52,250 And we're going to be passed the instance that we need to tween the tween info and the goal property. 310 00:18:52,820 --> 00:18:57,730 And then here on the client is where we can basically actually require the tween service. 311 00:18:57,730 --> 00:19:01,030 So we can do game, get service, tween service. 312 00:19:02,020 --> 00:19:07,960 And then we can just basically do tween service, create and pass the instance, the tween info and 313 00:19:07,960 --> 00:19:08,680 the goal. 314 00:19:08,920 --> 00:19:10,660 And then we can just play the tween. 315 00:19:10,690 --> 00:19:15,820 I don't technically need to store the return of this inside of a variable, unless I need to access 316 00:19:15,820 --> 00:19:16,690 the events or something. 317 00:19:16,690 --> 00:19:21,640 I can call the play function directly on the return value of this tween. 318 00:19:21,640 --> 00:19:27,160 But just to make it a little bit more readable, let's go ahead and make a variable called tween, and 319 00:19:27,160 --> 00:19:29,530 then we'll call the play function on the tween. 320 00:19:30,010 --> 00:19:36,700 So now just as a quick test to make sure that data is being passed properly to the clients, let's head 321 00:19:36,700 --> 00:19:40,030 over to the script for handling our color part. 322 00:19:40,030 --> 00:19:46,790 And instead of creating the tween and playing it on the server, let's go ahead and require our better 323 00:19:46,790 --> 00:19:54,800 tween module instead so we can do game, get service replicated storage dot better tween. 324 00:19:54,800 --> 00:19:58,490 And we need to require that module. 325 00:19:58,490 --> 00:20:05,690 And then instead of doing tween service create, all we need to do is we just need to call the tween 326 00:20:05,690 --> 00:20:11,830 function and pass our instance, our tween info and our goal. 327 00:20:12,190 --> 00:20:17,200 So let's go ahead and see if this works by hopping into the game and playing. 328 00:20:17,860 --> 00:20:19,540 And let's go ahead and see what happens. 329 00:20:20,380 --> 00:20:21,370 Uh oh. 330 00:20:21,400 --> 00:20:26,020 We've got an error inside of our local script on line seven. 331 00:20:26,020 --> 00:20:28,660 Argument two missing or nil. 332 00:20:28,690 --> 00:20:31,700 So let's go ahead and take a look at what this error message means. 333 00:20:31,730 --> 00:20:34,190 So the argument number two is missing. 334 00:20:34,190 --> 00:20:40,160 Or aka our tween info did not get passed to our client. 335 00:20:40,160 --> 00:20:41,840 Why is that what's going on. 336 00:20:41,840 --> 00:20:44,750 So let's figure out what's going on real quick. 337 00:20:44,750 --> 00:20:49,490 And let's print the instance, the tween info and the goal table. 338 00:20:49,940 --> 00:20:54,770 And then let's play our game again and let's go ahead and see what we get. 339 00:20:55,310 --> 00:21:01,060 We get nil nil and we get only our goal table. 340 00:21:01,090 --> 00:21:03,700 That is an issue, right? 341 00:21:03,730 --> 00:21:10,510 So what's going on here is that the first value is nil, because the client may not have replicated 342 00:21:10,510 --> 00:21:13,780 this part on their local copy of the game yet. 343 00:21:13,810 --> 00:21:21,630 So to account for that, if there is no instance, then we're just going to simply not do anything. 344 00:21:21,630 --> 00:21:28,500 And that's because this instance was not yet replicated to the client. 345 00:21:28,500 --> 00:21:30,480 So we're just going to not do anything. 346 00:21:30,480 --> 00:21:36,120 Now, I can fix this issue quite easily by setting a property in the workspace called streaming enabled 347 00:21:36,120 --> 00:21:37,080 to false. 348 00:21:37,080 --> 00:21:41,790 So that way when the player joins the game, all of the parts in the workspace will be instantaneously 349 00:21:41,790 --> 00:21:42,270 available. 350 00:21:42,270 --> 00:21:44,660 So I won't run into this issue right away. 351 00:21:44,960 --> 00:21:48,350 So let's just play test the game real quick. 352 00:21:48,710 --> 00:21:52,940 And actually let's move this print statement to be the first thing. 353 00:21:54,260 --> 00:21:59,420 And then let's see if we fix the first argument okay. 354 00:21:59,420 --> 00:22:01,520 We're still getting nil for some reason. 355 00:22:01,520 --> 00:22:07,250 So that might be because we're not passing the correct argument to the tween function. 356 00:22:07,250 --> 00:22:08,860 So let's go back to our script. 357 00:22:08,860 --> 00:22:10,000 Ah, that's the issue. 358 00:22:10,390 --> 00:22:12,460 I don't know why I just typed instance here. 359 00:22:12,460 --> 00:22:15,850 What we need to pass here is the part. 360 00:22:15,850 --> 00:22:17,560 The part okay. 361 00:22:17,920 --> 00:22:24,250 Now if we play test the game and we take a look at the arguments there, we get our part which is right 362 00:22:24,250 --> 00:22:25,390 there in the workspace. 363 00:22:25,390 --> 00:22:31,790 We get our goal table, but our tween info is still missing what is going on? 364 00:22:32,330 --> 00:22:36,230 Well, unfortunately this is a Roblox limitation. 365 00:22:36,230 --> 00:22:44,960 We are not able to pass tween infos through remote events, so a way to circumvent this issue is that 366 00:22:44,960 --> 00:22:51,260 we should instead pass a table to the client that contains all of the arguments for the tween info, 367 00:22:51,260 --> 00:22:55,960 and then the client can create the tween info, you know, on the client side. 368 00:22:55,960 --> 00:23:01,000 So what we should do instead here on the server side in our module script is we should create a new 369 00:23:01,000 --> 00:23:01,630 table. 370 00:23:01,630 --> 00:23:03,520 I'm just going to call it tween data. 371 00:23:03,850 --> 00:23:09,520 And what it's going to be equal to is just a list of all of the properties for the tween info. 372 00:23:09,520 --> 00:23:17,650 So if we look at tween info dot new, these are the properties that we need to pass in order to our 373 00:23:17,650 --> 00:23:18,160 array. 374 00:23:18,160 --> 00:23:20,370 So the first one is going to be time. 375 00:23:20,370 --> 00:23:25,530 So let's do tween info dot time. 376 00:23:25,530 --> 00:23:29,250 This is a property that exists within our tween info. 377 00:23:29,280 --> 00:23:33,300 Then we also need to get the easing style. 378 00:23:33,300 --> 00:23:35,100 So we're going to do easing style. 379 00:23:35,910 --> 00:23:38,790 And then actually to make this a little bit easier to see. 380 00:23:38,790 --> 00:23:40,830 So we can actually see the properties appearing. 381 00:23:40,830 --> 00:23:42,900 I'm going to do something a little bit fancy here. 382 00:23:42,900 --> 00:23:47,120 I'm going to type annotate this as a tween info. 383 00:23:47,150 --> 00:23:48,260 Don't worry about this. 384 00:23:48,260 --> 00:23:48,830 For right now. 385 00:23:48,830 --> 00:23:51,860 We're going to learn about type annotation much later in the course. 386 00:23:51,860 --> 00:23:57,620 But just for readability sake and teachability sake, I'm going to denote this as a tween info. 387 00:23:57,620 --> 00:24:03,590 So that way the linter or the intellisense or the autocomplete knows what this is. 388 00:24:03,590 --> 00:24:05,660 And now we can see all of the properties. 389 00:24:05,660 --> 00:24:07,310 So we've already got the time. 390 00:24:07,310 --> 00:24:08,950 We've already got the easing style. 391 00:24:08,950 --> 00:24:12,130 The next thing we need to get is the easing direction. 392 00:24:13,630 --> 00:24:17,380 The next thing is going to be the repeat count. 393 00:24:18,730 --> 00:24:22,810 The next property is going to be whether or not this tween reverses. 394 00:24:23,230 --> 00:24:28,330 And finally we're going to need the delay time property. 395 00:24:28,510 --> 00:24:35,220 So now instead of passing this tween info to the client, let's pass the tween data instead. 396 00:24:35,610 --> 00:24:37,560 And then back in our local script. 397 00:24:37,560 --> 00:24:44,940 When we get this tween data, we basically need to take all of those values inside of the array and 398 00:24:44,940 --> 00:24:50,310 pass it to the constructor for the tween info dot new. 399 00:24:50,310 --> 00:24:57,520 So we need to pass all those values into this constructor and then create our own tween info and that 400 00:24:57,520 --> 00:24:59,920 will get passed to the create function. 401 00:24:59,920 --> 00:25:04,720 So let me just fix this here and rename that to tween data. 402 00:25:04,810 --> 00:25:10,810 The easiest way to do this is to use a function in the table library called table dot unpack. 403 00:25:10,840 --> 00:25:15,730 It says returns all elements from the given list as a tuple or a list or whatever. 404 00:25:15,730 --> 00:25:24,070 It's just going to toss all of the values inside of our array and pass it to our constructor. 405 00:25:24,070 --> 00:25:27,820 So we're just going to do table dot unpack tween data. 406 00:25:28,510 --> 00:25:29,140 Okay. 407 00:25:29,140 --> 00:25:33,670 So now let's play test the game and see if we get any issues. 408 00:25:34,570 --> 00:25:35,860 And look at that. 409 00:25:35,890 --> 00:25:36,790 No issues. 410 00:25:36,790 --> 00:25:40,390 And we are playing the tween on the client side. 411 00:25:40,390 --> 00:25:42,880 We got our color part successfully on the client. 412 00:25:42,880 --> 00:25:49,850 We got all of the information we needed for the tween info, and we also got our goal table. 413 00:25:50,660 --> 00:25:56,000 Now there's another issue we need to fix if we take a look at the server side because the server did 414 00:25:56,000 --> 00:26:00,290 not play the tween, this is what the part looks like on the server. 415 00:26:00,290 --> 00:26:03,080 But for my client the part looks like this. 416 00:26:03,080 --> 00:26:09,370 This is going to be an issue, because if you want to sync these changes to any new clients that join 417 00:26:09,370 --> 00:26:15,880 the game in the future, we need to set the goal properties on this part on the server. 418 00:26:15,880 --> 00:26:17,800 So actually let me just copy that. 419 00:26:17,800 --> 00:26:19,660 Let's go to the client view. 420 00:26:20,080 --> 00:26:21,460 Let's copy the color. 421 00:26:22,660 --> 00:26:24,340 Let's paste that there. 422 00:26:24,550 --> 00:26:26,980 And then let's copy the size as well. 423 00:26:28,300 --> 00:26:31,900 And we'll paste that in the size as well. 424 00:26:32,310 --> 00:26:34,830 So this is what we want our part to look like on the server. 425 00:26:35,490 --> 00:26:41,700 So in order to do that, what we need to do inside of our better tween module is we need to wait until 426 00:26:41,700 --> 00:26:42,930 the tween is over. 427 00:26:42,930 --> 00:26:46,980 So we need to include the time, the delay time. 428 00:26:46,980 --> 00:26:51,360 If the tween repeats, we basically need to calculate the total time we need to wait. 429 00:26:51,360 --> 00:26:56,540 And then after that total time is up, we can apply all of the properties on our tween. 430 00:26:56,540 --> 00:26:58,910 So let's go ahead and create a variable. 431 00:26:58,910 --> 00:27:01,970 And we're going to call this total time. 432 00:27:01,970 --> 00:27:07,730 And the total time is going to be equal to the tween info dot time. 433 00:27:08,480 --> 00:27:15,650 And then this is going to have to be added with the tween info dot delay time. 434 00:27:16,430 --> 00:27:24,120 And then we need to multiply these two values by the number of time this tween repeats. 435 00:27:25,380 --> 00:27:32,730 So we can do multiply by tween info dot repeat count. 436 00:27:32,880 --> 00:27:34,530 Now there's one more thing we need to do. 437 00:27:34,560 --> 00:27:37,500 We need to add one to the repeat count. 438 00:27:37,530 --> 00:27:38,820 Why do we need to do this. 439 00:27:38,850 --> 00:27:44,190 Well it's because the repeat count by default is going to be a value of zero, which basically means 440 00:27:44,190 --> 00:27:45,800 the tween plays once. 441 00:27:45,800 --> 00:27:50,420 And if we multiply these values by zero, our total time is going to be zero. 442 00:27:50,420 --> 00:27:51,950 And that's not correct. 443 00:27:51,950 --> 00:27:58,610 So if the tween info repeat count is set to one, that means we need to add that extra one to multiply 444 00:27:58,610 --> 00:28:04,100 the time, for example, by two, which means there is two tweens playing because the repeat count is 445 00:28:04,100 --> 00:28:04,640 set to one. 446 00:28:04,640 --> 00:28:11,510 So now what we need to do is we basically need to delay a function from running for this amount of time. 447 00:28:11,510 --> 00:28:16,520 And then once that time is over, we apply all of the properties on our part. 448 00:28:16,520 --> 00:28:21,770 And a way we can do this is using the task library, which we learned about in a previous lecture. 449 00:28:21,770 --> 00:28:28,400 Let's go ahead and use the task dot delay function to delay for this total time. 450 00:28:28,610 --> 00:28:34,830 We're going to delay a function from executing and once that time is over, we can basically just loop 451 00:28:34,830 --> 00:28:40,020 through all of the properties inside of the goal table and apply those properties on our instance. 452 00:28:40,500 --> 00:28:48,930 So we can do for every single property, name and value inside of pairs goal table. 453 00:28:48,930 --> 00:28:54,540 What we want to do is we want to refer to our instance, index it with this particular property name 454 00:28:54,540 --> 00:28:57,950 and set it equal to the new value. 455 00:28:58,610 --> 00:29:01,550 So now let's go ahead and play our game. 456 00:29:04,640 --> 00:29:08,420 And here it is Tweening on the client side. 457 00:29:08,900 --> 00:29:11,930 And then eventually once the tween is finished. 458 00:29:12,980 --> 00:29:14,570 Let's just wait a few more seconds. 459 00:29:14,600 --> 00:29:15,020 Okay. 460 00:29:15,020 --> 00:29:18,260 The tween should be done if we go and check the server view. 461 00:29:18,380 --> 00:29:19,340 Look at that. 462 00:29:19,340 --> 00:29:27,410 The server has also updated the property to match the new color and the new size that we assign for 463 00:29:27,410 --> 00:29:28,070 in our tween. 464 00:29:28,070 --> 00:29:33,650 So now any future clients that join our game are going to see the size and the color of our property 465 00:29:33,650 --> 00:29:36,440 set to the new correct size and color. 466 00:29:36,440 --> 00:29:39,350 But we have another issue. 467 00:29:39,380 --> 00:29:49,730 The other issue is what if we played a tween on this instance while another tween was being waited for, 468 00:29:49,820 --> 00:29:56,060 and this other tween delays sets the properties while we're waiting for the tween on the other object. 469 00:29:56,060 --> 00:29:57,980 So I'll show you what I mean. 470 00:29:58,010 --> 00:30:00,050 Let's say we tween right. 471 00:30:00,050 --> 00:30:03,200 We're going to tween, which takes 10s. 472 00:30:03,200 --> 00:30:09,370 But let's say, I don't know, five seconds down the line in our game, the tween plays on our part 473 00:30:09,370 --> 00:30:14,410 again, but instead we're modifying the size and the color to something different. 474 00:30:14,410 --> 00:30:20,710 So real quick, let's just set the size equal to a new random size like one, one one. 475 00:30:20,710 --> 00:30:24,730 And let's set the color equal to some kind of random color three. 476 00:30:24,730 --> 00:30:26,140 So color three dot new. 477 00:30:26,140 --> 00:30:28,480 Let's just do black right. 478 00:30:28,480 --> 00:30:30,700 So we're playing this first tween. 479 00:30:30,700 --> 00:30:34,710 And then five seconds later we're going to be playing this second tween. 480 00:30:34,710 --> 00:30:37,830 And we're going to see a little bit of a conflict going on here. 481 00:30:37,830 --> 00:30:41,430 And then finally actually let me adjust this tween info to be shorter. 482 00:30:41,430 --> 00:30:45,330 So we're just going to do a tween info of just one second. 483 00:30:45,330 --> 00:30:47,940 So we're going to have a timing conflict an issue here. 484 00:30:47,940 --> 00:30:54,330 So if we play the game we're going to see the client perform the first tween which increases the size 485 00:30:54,330 --> 00:30:55,230 and changes the color. 486 00:30:55,230 --> 00:30:58,250 But after five seconds that tween is going to be overwritten. 487 00:30:58,280 --> 00:30:59,900 There we go by our new tween. 488 00:30:59,930 --> 00:31:03,800 So now this is the result of our object on all the clients in our game. 489 00:31:03,800 --> 00:31:06,260 Oh, whoa, look at that. 490 00:31:06,620 --> 00:31:07,820 You see the issue? 491 00:31:07,850 --> 00:31:12,890 The server just set the property to that other tween that we were still waiting for. 492 00:31:13,160 --> 00:31:16,520 Remember that one tween that had a time of 10s? 493 00:31:16,550 --> 00:31:22,810 Well, that delay time finally went up and it set the properties on our instance to those old properties 494 00:31:22,810 --> 00:31:24,730 when it should have gotten overwritten. 495 00:31:25,090 --> 00:31:32,530 So a way we can fix this issue is we need to basically store the thread or the coroutine created by 496 00:31:32,530 --> 00:31:37,540 the delay function, and we can store it in a table and use the instance as the key. 497 00:31:37,570 --> 00:31:44,440 That way if this function gets called again and we're trying to tween the same instance while another 498 00:31:44,440 --> 00:31:45,720 tween is active. 499 00:31:45,720 --> 00:31:50,070 We're basically going to cancel that previous tween and instead do the new tween. 500 00:31:50,100 --> 00:31:52,560 So this is very simple to do. 501 00:31:53,490 --> 00:31:56,010 We can just create a table. 502 00:31:56,010 --> 00:31:59,190 We'll call this active tweens. 503 00:32:00,450 --> 00:32:07,590 And inside of the active tweens table we're going to use our instance as the key in this table. 504 00:32:08,340 --> 00:32:13,810 And we're going to store the thread that gets returned by task dot delay. 505 00:32:13,810 --> 00:32:18,790 So let me move this down here and we'll set that equal to this thread. 506 00:32:20,110 --> 00:32:26,110 So now what we can do is we can check if there is an active thread on this particular instance. 507 00:32:26,110 --> 00:32:31,330 So when we call the tween function what we're going to do is we're going to check if there is an active 508 00:32:31,330 --> 00:32:33,630 tween or this instance. 509 00:32:33,630 --> 00:32:36,990 If there is, we need to cancel it. 510 00:32:36,990 --> 00:32:40,230 So let's go ahead and do task dot cancel. 511 00:32:40,230 --> 00:32:44,220 And we need to pass the active thread. 512 00:32:44,220 --> 00:32:45,750 And we should be good to go. 513 00:32:45,750 --> 00:32:51,270 So let's play test the game again and see if that has resolved our timing issue. 514 00:32:51,270 --> 00:32:56,640 So here are the first tween is playing and then the second tween plays. 515 00:32:56,670 --> 00:33:02,580 And let's see if the server sets the property for this part to those old properties. 516 00:33:03,300 --> 00:33:04,260 And we're waiting. 517 00:33:04,260 --> 00:33:05,040 We're waiting. 518 00:33:05,580 --> 00:33:06,690 Looks like we fixed it. 519 00:33:06,690 --> 00:33:08,820 Let's go ahead and take a look at the server view. 520 00:33:08,820 --> 00:33:09,990 And perfect. 521 00:33:09,990 --> 00:33:13,500 The server has the exact same view as the client. 522 00:33:13,500 --> 00:33:19,410 One more important thing we need to do is that after we are done delaying and applying the properties, 523 00:33:19,410 --> 00:33:27,910 we need to go ahead and remove that tween out of the active tweens table to clean up memory so we can 524 00:33:27,910 --> 00:33:29,260 do active tweens. 525 00:33:29,290 --> 00:33:33,490 Instance is equal to nil just like that. 526 00:33:33,490 --> 00:33:39,880 So now we basically have a working tween system on the server that we can use that will notify all the 527 00:33:39,880 --> 00:33:40,930 clients in our game. 528 00:33:40,930 --> 00:33:45,900 And once the tween is over, the server goes through and applies all of the correct properties. 529 00:33:45,900 --> 00:33:51,930 So any new clients in the future that join will see the correct properties on a particular instance. 530 00:33:51,930 --> 00:33:57,810 Now just to clean this up a little bit more, let's go ahead and move this function into its own function 531 00:33:57,810 --> 00:34:01,980 outside of this scope, this scope of the tween function. 532 00:34:02,130 --> 00:34:06,060 Let's call this function tween completed. 533 00:34:06,360 --> 00:34:12,230 And we're going to need to be passed the instance and the goal. 534 00:34:13,100 --> 00:34:21,170 And then we can just basically copy this code here, paste it inside of there, and instead we can delay 535 00:34:21,860 --> 00:34:27,020 our tween completed function and the arguments we need to pass to. 536 00:34:27,020 --> 00:34:28,460 It's going to be the instance and the goal. 537 00:34:28,460 --> 00:34:32,330 So we can pass instance and we can pass the goal. 538 00:34:32,330 --> 00:34:37,110 So these two arguments will automatically get passed to our tween completed function. 539 00:34:37,110 --> 00:34:39,780 And it should do the exact same thing. 540 00:34:40,050 --> 00:34:46,800 And now one more thing I promise we need to account for if the repeat count is negative one, which 541 00:34:46,800 --> 00:34:51,450 is an issue because we can't really loop tweens on the server with this setup. 542 00:34:51,450 --> 00:35:03,470 So as basically a band aid fix, what we can do is we can check if tween info dot repeat count is equal 543 00:35:03,470 --> 00:35:04,910 to negative one. 544 00:35:04,910 --> 00:35:12,590 If it is, then we can just basically give out a warning and we could say cannot repeat tweens with 545 00:35:12,590 --> 00:35:16,550 better tween or something like that, because that's a little bit of a headache we don't want to deal 546 00:35:16,550 --> 00:35:18,020 with and we'll just return. 547 00:35:18,110 --> 00:35:19,430 Okay, I lied. 548 00:35:19,430 --> 00:35:24,530 There's actually one more thing we need to do with our better twin module, and we need to account for 549 00:35:24,530 --> 00:35:27,710 if this reverse is property is set to true. 550 00:35:27,710 --> 00:35:29,660 And I'll show you why here in a second. 551 00:35:29,660 --> 00:35:34,190 So let's go back to our script that handles resizing or tweening that part. 552 00:35:34,850 --> 00:35:36,680 And I'm going to delete this. 553 00:35:36,680 --> 00:35:40,160 And what we want to do is let's go to modify this tween info. 554 00:35:40,160 --> 00:35:43,070 We'll just do an enum easing style of linear. 555 00:35:43,070 --> 00:35:51,390 We'll do an enum easing direction of the regular in because we want to get to, uh, the reverses. 556 00:35:51,390 --> 00:35:54,180 Let's just set the repeat count to one and then reverses. 557 00:35:54,180 --> 00:35:55,680 We're going to set this to true. 558 00:35:55,980 --> 00:35:57,450 Um, okay. 559 00:35:57,450 --> 00:35:57,720 Yeah. 560 00:35:57,750 --> 00:35:58,290 Good. 561 00:35:58,290 --> 00:36:00,390 We'll set reverse is equal to true. 562 00:36:00,390 --> 00:36:05,130 So what's going to happen is that this tween is going to play. 563 00:36:05,130 --> 00:36:06,720 It's going to go to the goal. 564 00:36:06,720 --> 00:36:09,680 And then it's going to reverse and go back to its default state. 565 00:36:10,190 --> 00:36:12,260 That is what this part is going to do. 566 00:36:12,440 --> 00:36:14,360 Let's decrease the time here. 567 00:36:14,750 --> 00:36:16,820 And that looks good. 568 00:36:16,820 --> 00:36:19,100 So let's go and play test the game. 569 00:36:21,050 --> 00:36:23,930 And we're going to have this tween happen here. 570 00:36:25,790 --> 00:36:32,570 And what the issue is going to be is I think the server is going to prematurely. 571 00:36:32,570 --> 00:36:34,390 Yeah there's your issue. 572 00:36:34,900 --> 00:36:36,820 There is your issue. 573 00:36:36,910 --> 00:36:43,090 The tween ended prematurely and it also set it to the wrong property. 574 00:36:43,090 --> 00:36:46,120 The tween should be oh it's still playing okay. 575 00:36:46,120 --> 00:36:49,120 Let's just keep it playing and see what the end goal is. 576 00:36:51,160 --> 00:36:54,040 We'll get to the end goal okay perfect. 577 00:36:54,040 --> 00:36:57,370 This is what the tween should look like for all the clients in the game. 578 00:36:57,380 --> 00:37:00,830 But if we look at the server, this is very wrong. 579 00:37:00,830 --> 00:37:02,810 This is not what we want at all. 580 00:37:03,020 --> 00:37:07,490 And that's because we did not account for this reverse property. 581 00:37:07,490 --> 00:37:13,700 So basically what we need to do is we need to multiply the time by two. 582 00:37:13,730 --> 00:37:15,380 If reverses is set to two. 583 00:37:15,380 --> 00:37:19,190 Otherwise we can just multiply it by one and or just leave time the same. 584 00:37:19,190 --> 00:37:22,210 So let's make a variable called time multiplier. 585 00:37:22,900 --> 00:37:27,610 And what we need to do is we need to check if reverses is set to true. 586 00:37:27,640 --> 00:37:33,190 So I'm going to do an if then else expression here real quick, which is basically an easier to read 587 00:37:33,190 --> 00:37:41,980 version of using those expressions that we saw earlier like and and or so like I could do tween info 588 00:37:41,980 --> 00:37:47,760 dot reverses and 2 or 1, but that's a little bit hard to read. 589 00:37:47,790 --> 00:37:55,830 A little easier way to read this would be if tween info dot reverses, then the value we're going to 590 00:37:55,830 --> 00:37:59,280 set in time multiplier is going to be two. 591 00:37:59,310 --> 00:38:01,020 Otherwise it's going to be one. 592 00:38:01,020 --> 00:38:03,630 This is an if then else expression. 593 00:38:03,630 --> 00:38:07,380 It's not an if then else statement because there's no end keyword here. 594 00:38:07,380 --> 00:38:08,520 We don't need that. 595 00:38:09,410 --> 00:38:15,890 We are using this as a way to store a value in a variable based on a condition. 596 00:38:16,100 --> 00:38:23,180 So now what we can do is we can multiply twin info dot time by this time multiplier. 597 00:38:23,930 --> 00:38:31,700 And if we do reverse we basically just need to not apply any of the gold properties because it's going 598 00:38:31,700 --> 00:38:33,500 to go back to its default state. 599 00:38:33,880 --> 00:38:43,300 So the easiest way we could do that is we could pass our tween info to the tween completed function, 600 00:38:43,540 --> 00:38:45,820 and then we could check in there if it reverses. 601 00:38:45,820 --> 00:38:47,560 And if it does we don't do anything. 602 00:38:47,680 --> 00:38:49,540 Or we could do some other way. 603 00:38:49,540 --> 00:38:50,860 But let's just do that for now. 604 00:38:51,760 --> 00:39:03,690 We can get the tween info and if this tween info reverses, then we basically do nothing. 605 00:39:03,690 --> 00:39:05,730 But we still need to set this equal to nil. 606 00:39:05,730 --> 00:39:13,800 So actually if the tween info does not reverse, we'll apply the properties and then we'll make sure 607 00:39:13,800 --> 00:39:16,710 to set active tweens for this instance equal to nil. 608 00:39:16,740 --> 00:39:17,400 Okay. 609 00:39:18,060 --> 00:39:20,970 So now that issue we just saw should be resolved. 610 00:39:20,970 --> 00:39:22,870 So let's go back and play test. 611 00:39:24,580 --> 00:39:27,370 And let's wait for that tween to finish up. 612 00:39:32,380 --> 00:39:33,010 Okay. 613 00:39:33,010 --> 00:39:35,350 There is the final result for the tween. 614 00:39:35,350 --> 00:39:36,640 Let's check the server. 615 00:39:36,640 --> 00:39:38,020 And perfect. 616 00:39:38,020 --> 00:39:39,610 The server didn't do anything. 617 00:39:39,610 --> 00:39:43,780 And the part looks correct on both the client and the server. 618 00:39:43,810 --> 00:39:46,500 Man I keep telling you we're done and I keep lying to you. 619 00:39:46,500 --> 00:39:52,770 I'm so sorry, but one more thing I've added to the better tween tween function is I just return the 620 00:39:52,770 --> 00:39:53,640 total amount of time. 621 00:39:53,640 --> 00:39:59,760 So that way, anyone who's calling this function knows how long to wait for until the tween is finished. 622 00:39:59,760 --> 00:40:02,190 That's the last thing I am doing. 623 00:40:02,220 --> 00:40:02,790 All right. 624 00:40:02,790 --> 00:40:07,560 Just to make sure you understand everything, we're just going to do a quick recap with our better tween 625 00:40:07,560 --> 00:40:09,540 module and how it works. 626 00:40:09,540 --> 00:40:13,700 So we have a function in our better tween module called tween. 627 00:40:13,700 --> 00:40:20,000 And it's basically us just copying or replicating the create constructor function that is in the tween 628 00:40:20,000 --> 00:40:20,390 service. 629 00:40:20,390 --> 00:40:26,390 So we get passed the instance we want a tween, the tween info for the tween, and the goal table of 630 00:40:26,390 --> 00:40:28,310 properties that we want a tween to. 631 00:40:28,310 --> 00:40:34,810 And since this system tells all of the clients to play the tween, it's kind of difficult for us to 632 00:40:34,810 --> 00:40:38,680 be able to track, for example, an infinite tween. 633 00:40:38,710 --> 00:40:45,670 So what we just do in the meantime is we just spit out a warning saying, hey, we can't play any tweens 634 00:40:45,670 --> 00:40:50,680 on the server side using this module when the repeat count is set to negative one, which means this 635 00:40:50,680 --> 00:40:52,600 tween goes on forever and ever. 636 00:40:52,600 --> 00:40:53,800 And that's kind of an issue. 637 00:40:53,800 --> 00:40:55,720 So we just say, hey, we can't do that. 638 00:40:56,290 --> 00:40:56,890 Otherwise. 639 00:40:56,890 --> 00:41:03,700 What we need to do is we need to check if this instance already has a tween active in our active tweens 640 00:41:03,700 --> 00:41:07,240 table, and we use the instance as the key in the table. 641 00:41:07,240 --> 00:41:11,470 And if there is a current thread in here, maybe it's suspended or whatever. 642 00:41:11,470 --> 00:41:17,170 We use the task dot cancel function to cancel that thread and make way for the new thread we're about 643 00:41:17,170 --> 00:41:17,890 to create. 644 00:41:17,890 --> 00:41:24,180 So then we take our tween info, we unpack all of its data and place it into a tween data table. 645 00:41:24,180 --> 00:41:28,980 That way we can actually pass it through our remote event, because for some reason we aren't able to 646 00:41:28,980 --> 00:41:31,170 send tween infos through remote events. 647 00:41:31,170 --> 00:41:32,520 So we need to do it this way. 648 00:41:32,520 --> 00:41:36,180 And then the next thing we need to do is calculate the total time for the tween. 649 00:41:36,180 --> 00:41:43,710 Now if this tween reverses, we need to multiply our time by basically two to account for if the tween 650 00:41:43,710 --> 00:41:44,160 reverses. 651 00:41:44,160 --> 00:41:45,390 So we check. 652 00:41:45,390 --> 00:41:48,780 If the tween reverses then we're going to set time multiplier to two. 653 00:41:48,780 --> 00:41:50,220 Otherwise we just set it to one. 654 00:41:50,220 --> 00:41:54,840 And then we calculate the total time, which is going to be the duration of the tween multiplied by 655 00:41:54,840 --> 00:41:56,070 that time multiplier. 656 00:41:56,070 --> 00:41:59,640 And then we need to add if there is going to be a delay time. 657 00:41:59,640 --> 00:42:05,610 And then once we get this value, we need to multiply it by how many times this tween repeats. 658 00:42:05,610 --> 00:42:08,910 By default this is set to zero, which is why we're adding one here. 659 00:42:08,910 --> 00:42:14,810 Because if we multiply this number by zero, we're just going to get a total time of zero, which isn't 660 00:42:14,810 --> 00:42:15,500 what we want. 661 00:42:15,500 --> 00:42:19,970 And then once we're done calculating the total time, we're going to delay a new coroutine. 662 00:42:19,970 --> 00:42:23,030 So we're going to pass the total time, however long that is. 663 00:42:23,030 --> 00:42:27,800 And after that time is up, we're going to execute our tween completed function. 664 00:42:27,800 --> 00:42:33,770 And then these values that we're passing to the task dot delay function after this one are going to 665 00:42:33,770 --> 00:42:37,630 be all of the arguments we're passing to the tween completed function. 666 00:42:37,630 --> 00:42:40,660 Once this total time is up, it'll go in here and execute this function. 667 00:42:40,660 --> 00:42:44,800 But before we do that, we're going to set in our active tweens table. 668 00:42:44,800 --> 00:42:46,810 Set it equal to this instance. 669 00:42:46,810 --> 00:42:50,140 And we're going to store the new thread or the coroutine. 670 00:42:50,440 --> 00:42:52,000 And then we fire to all the clients. 671 00:42:52,000 --> 00:42:57,910 Hey play this tween and we return the total amount of time that this tween plays for. 672 00:42:57,910 --> 00:43:03,450 And then inside of our local script that's listening to that event, we get passed the instance that 673 00:43:03,450 --> 00:43:07,710 table containing all of the data for the tween as well as the goal table. 674 00:43:07,710 --> 00:43:13,500 If we do not have access to this instance on the client side, it could be maybe this instance hasn't 675 00:43:13,500 --> 00:43:15,690 been replicated yet or something like that. 676 00:43:15,690 --> 00:43:19,650 Then we're just going to return because we can't do anything otherwise. 677 00:43:19,650 --> 00:43:27,050 We take our tween data table and we unpack all of the values in there and give it to our tween info 678 00:43:27,050 --> 00:43:27,920 dot new function. 679 00:43:27,920 --> 00:43:31,670 So that way we actually have a tween info data type on the client side. 680 00:43:31,670 --> 00:43:35,900 And then we can pass that information to the tween service create function. 681 00:43:35,900 --> 00:43:40,430 So we give it the instance, we give it the tween info, we give it the goal and we simply play the 682 00:43:40,430 --> 00:43:40,880 tween. 683 00:43:40,880 --> 00:43:44,330 Now when the tween is over, let's say this total time duration is up. 684 00:43:44,330 --> 00:43:49,660 It's going to execute this function, which just basically checks to see if the tween info does not 685 00:43:49,660 --> 00:43:54,640 reverse, and if it does not reverse, it's going to go through every single property and value inside 686 00:43:54,640 --> 00:43:58,540 of the goal table and apply it on the instance on the server side. 687 00:43:58,540 --> 00:44:03,700 That way, any future clients that join our game are going to have the same properties applied on the 688 00:44:03,700 --> 00:44:04,180 instance. 689 00:44:04,180 --> 00:44:09,460 So that way none of the clients in the game are out of sync based on whatever property we're Tweening 690 00:44:09,460 --> 00:44:14,750 if the tween does reverse, then there's no point for us to apply any of the goal properties because 691 00:44:14,750 --> 00:44:20,060 it'll go and tween to the goal properties, and then it reverses and just goes back to its regular state. 692 00:44:20,060 --> 00:44:22,580 So there's no point applying any of the properties. 693 00:44:22,580 --> 00:44:28,970 And then once that's done, we need to make sure we clear this instance and the key and the value out 694 00:44:28,970 --> 00:44:30,380 of our active tweens table. 695 00:44:30,380 --> 00:44:31,850 So we just set it equal to nil. 696 00:44:31,850 --> 00:44:34,720 And that's how our better tween system works. 697 00:44:34,840 --> 00:44:35,530 Alrighty. 698 00:44:35,530 --> 00:44:40,240 So this was a butt ton of information I just threw at your face. 699 00:44:40,240 --> 00:44:42,190 I'm sorry, but I'm also not sorry. 700 00:44:42,190 --> 00:44:47,260 After this lecture, you're going to attempt a quiz, and then we're going to practice using our better 701 00:44:47,260 --> 00:44:55,450 tween module in another lecture for creating this sliding door that opens and then we're able to close 702 00:44:55,450 --> 00:44:55,840 it. 703 00:44:55,840 --> 00:44:59,140 So thank you for watching and I will see you there.